package ijournalimporter.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.URL;
import java.net.UnknownHostException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.Deflater;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import javax.swing.filechooser.FileSystemView;

/**
 *
 * @author eric
 */
public class Util {

    private static final int READ_WRITE_BUF = 32768; // 32K

    public static BufferedReader getBufferedReader(String filename, String encoding) {
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(filename), encoding), READ_WRITE_BUF);
            return br;
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(Util.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        } catch (FileNotFoundException ex) {
            Logger.getLogger(Util.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
    }

    public static BufferedReader getBufferedReader(String filename) {
        return getBufferedReader(filename, "UTF-8");
    }

    public static BufferedWriter getBufferedWriter(String filename, boolean append) {
        return getBufferedWriter(filename, "UTF-8", append);
    }

    public static BufferedWriter getBufferedWriter(String filename, String encoding, boolean append) {
        try {
            BufferedWriter bw = null;
            bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filename, append), encoding), READ_WRITE_BUF);
            return bw;
        } catch (FileNotFoundException ex) {
            Logger.getLogger(Util.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(Util.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
    }

    public static BufferedWriter getBufferedWriter(String filename) {
        return Util.getBufferedWriter(filename, "UTF-8", true);
    }

    public static BufferedOutputStream getBufferedOutputStream(String filename) {
        BufferedOutputStream bos;
        try {
            bos = new BufferedOutputStream(new FileOutputStream(filename), READ_WRITE_BUF);
            return bos;
        } catch (FileNotFoundException ex) {
            Logger.getLogger(Util.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
    }

    public static BufferedOutputStream getBufferedOutputStream(File file) {
        return getBufferedOutputStream(file.getAbsolutePath());
    }

    public static BufferedInputStream getBufferedInputStream(String filename) {
        BufferedInputStream bis;
        try {
            bis = new BufferedInputStream(new FileInputStream(filename), READ_WRITE_BUF);
            return bis;
        } catch (FileNotFoundException ex) {
            Logger.getLogger(Util.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
    }

    public static BufferedInputStream getBufferedInputStream(File file) {
        return getBufferedInputStream(file.getAbsolutePath());
    }

    public static void writeToFile(String filename, String data) throws IOException {
        BufferedWriter writer = Util.getBufferedWriter(filename, true);
        writer.write(data);
        writer.flush();
        writer.close();
    }

    public static void writeToFile(String filename, String data, boolean append) throws IOException {
        BufferedWriter writer = Util.getBufferedWriter(filename, append);
        writer.write(data);
        writer.flush();
        writer.close();
    }

    public static boolean writeToFileNoWarning(String filename, String data) {
        BufferedWriter writer = null;
        try {
            writer = Util.getBufferedWriter(filename, true);
            writer.write(data);
            writer.flush();
            writer.close();
            return true;
        } catch (IOException ex) {
            Logger.getLogger(Util.class.getName()).log(Level.SEVERE, null, ex);
            return false;
        } finally {
            try {
                writer.close();
            } catch (Exception e) {
                Logger.getLogger(Util.class.getName()).log(Level.SEVERE, null, e);
                return false;
            }
        }
    }

    public static String readFileIntoString(String filename) {
        try {
            if (Util.isBlank(filename)) {
                return null;
            }
            StringBuffer sb = new StringBuffer();
            BufferedReader br = Util.getBufferedReader(filename);
            String line = null;
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }
            br.close();
            return sb.toString();
        } catch (IOException ex) {
            Logger.getLogger(Util.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
    }

    public static boolean binaryWrite(BufferedInputStream bis, BufferedOutputStream bos, int bufSize) {
        try {
            byte[] d = new byte[bufSize];
            int bytesRead = 0;
            while ((bytesRead = bis.read(d)) > 0) {
                bos.write(d, 0, bytesRead);
            }
            bos.flush();
            bis.close();
            bos.close();
            return true;
        } catch (IOException ex) {
            Logger.getLogger(Util.class.getName()).log(Level.SEVERE, null, ex);
            return false;
        }
    }

    public static boolean binaryWrite(BufferedInputStream bis, BufferedOutputStream bos) {
        return binaryWrite(bis, bos, READ_WRITE_BUF);
    }

    public static String getTodayWithTime() {
        SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
        return df.format(new Date());
    }

    public static String getToday() {
        SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
        return df.format(new Date());
    }

    public static String getTodayWithTime(SimpleDateFormat df) {
        return df.format(new Date());
    }

    public static String getTodayWithTime(String df) {
        return getTodayWithTime(new SimpleDateFormat(df));
    }

    public static String formatSerialNo(int numberOfZero, int serNo) {
        String noString = String.valueOf(serNo);

        int len = numberOfZero - noString.length();
        StringBuffer sb = new StringBuffer();

        for (int i = 0; i < len; i++) {
            sb.append("0");
        }

        sb.append(noString);
        return sb.toString();
    }

    public static Properties getProperties(String filename) {
        FileInputStream in = null;
        try {
            Properties props = new Properties();
            in = new FileInputStream(filename);
            props.load(in);
            in.close();
            return props;
        } catch (IOException ex) {
            //Logger.getLogger(Util.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
    }

    public static Properties readProperties(String filename) {
        return getProperties(filename);
    }

    public static boolean writeProperties(Properties props, String filename) {
        FileOutputStream out = null;
        try {
            out = new FileOutputStream(filename);
            props.store(out, "");
            out.flush();
            out.close();
            return true;
        } catch (IOException ex) {
            Logger.getLogger(Util.class.getName()).log(Level.SEVERE, null, ex);
            return false;
        }
    }

    public static String getPropertie(String filename, String key) {
        Properties prop = getProperties(filename);
        if (prop != null) {
            String rval = prop.getProperty(key, null);
            if (rval != null) {
                rval = rval.trim();
            }
            return rval;
        } else {
            return null;
        }
    }

    public static boolean putPropertie(String filename, String key, String value) {
        Properties prop = getProperties(filename);
        if (prop == null) {
            prop = new Properties();
        }
        prop.put(key, value);
        return writeProperties(prop, filename);
    }

    public static void delayMS(long millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException ie) {
            System.out.println(ie.getMessage());
        }
    }

    public static void delay(int sec) {
        delayMS(sec * 1000);
    }

    public static void println(Object obj) {
        System.out.println(obj);
    }

    public static void print(Object obj) {
        System.out.print(obj);
    }

    public static String getFilename(String file) {
        File f = new File(file);
        return f.getName();
    }

    public static String getFilenameWithoutExtention(String file) {
        File f = new File(file);
        String filename = f.getName();
        return filename.substring(0, filename.lastIndexOf('.'));
    }

    public static String getFileExtention(String filename) {
        try {
            String ext = filename.substring(filename.lastIndexOf('.') + 1, filename.length());
            return ext.toLowerCase();
        } catch (Exception e) {
            return null;
        }
    }

    public static String getFileExtention(File file) {
        return getFileExtention(file.getName());
    }

    public static long getFileSize(String filename) {
        File f = new File(filename);
        return f.length();
    }

    public static String getFilePath(String filename) {
        return new File(filename).getParent();

    }

    public static void deleteFile(String filename) {
        File f = new File(filename);
        if (f.isFile() && f.exists()) {
            f.delete();
        }
    }

    public static boolean isBlank(String str) {
        int strLen;
        if (str == null || (strLen = str.length()) == 0) {
            return true;
        }
        for (int i = 0; i < strLen; i++) {
            if ((Character.isWhitespace(str.charAt(i)) == false)) {
                return false;
            }
        }
        return true;
    }

    public static boolean isNotBlank(String str) {
        return !isBlank(str);
    }

    public static boolean zip(File source, File target) {
        return zip(source, target, Deflater.DEFAULT_COMPRESSION);
    }

    public static boolean zip(File source, File target, int level) {
        BufferedInputStream in = null;
        ZipOutputStream out = null;
        try {
            in = Util.getBufferedInputStream(source);
            out = new ZipOutputStream(Util.getBufferedOutputStream(target));
            out.setLevel(level);

            byte[] data = new byte[READ_WRITE_BUF];
            int count;
            out.putNextEntry(new ZipEntry(source.getName()));
            while ((count = in.read(data, 0, data.length)) != -1) {
                out.write(data, 0, count);
            }

            in.close();
            out.flush();
            out.close();
            return true;
        } catch (IOException ex) {
            Logger.getLogger(Util.class.getName()).log(Level.SEVERE, null, ex);
            return false;
        } finally {
            try {
                in.close();
                out.close();
            } catch (IOException ex) {
                Logger.getLogger(Util.class.getName()).log(Level.SEVERE, null, ex);
                return false;
            }
        }
    }

    public static boolean zip(String source, String target) {
        return zip(new File(source), new File(target), Deflater.DEFAULT_COMPRESSION);
    }

    public static boolean zip(String source, String target, int level) {
        return zip(new File(source), new File(target), level);
    }

    public static void logToFile(String logFile, String msg) throws IOException {
        StringBuffer bf = new StringBuffer();
        bf.append("[").append(Calendar.getInstance().getTime()).append("] ").append(msg);
        Util.writeToFile(logFile, bf.toString());
    }

    public static String getMachineIP() {
        try {
            InetAddress i = java.net.InetAddress.getLocalHost();
            return i.getHostAddress();
        } catch (UnknownHostException ex) {
            return null;
        }
    }

    public static String getIP(String host) {
        try {
            URL url = new URL(host);
            InetAddress ia = InetAddress.getByName(url.getHost());
            return ia.getHostAddress();
        } catch (Exception ex) {
            Logger.getLogger(Util.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
    }

    public static String getDesktopPath() {
        FileSystemView filesys = FileSystemView.getFileSystemView();
        return filesys.getHomeDirectory().getAbsolutePath() + "\\";
    }

    public static String getTempPath() {
        String tempDir = System.getProperty("java.io.tmpdir");
        return tempDir;
    }

    public static File[] listAllDirectories(File dir) {
        ArrayList<File> rval = new ArrayList();

        File[] children = dir.listFiles();
        if (children == null) {
            // Either dir does not exist or is not a directory
            return null;
        } else {
            for (int i = 0; i < children.length; i++) {
                // Get filename of file or directory
                File f = children[i];
                if (f.isDirectory()) {
                    rval.add(f);
                }
            }
        }

        if (!rval.isEmpty()) {
            return (File[]) rval.toArray(new File[rval.size()]);
        } else {
            return null;
        }
    }

    public static File[] listAllDirectories(String dir) {
        return listAllDirectories(new File(dir));
    }

    public static String toUTF8(String oldEncoding, String oldString) {
        if (Util.isBlank(oldString)) {
            return null;
        } else {
            try {
                return new String(oldString.getBytes(oldEncoding), "UTF-8");
            } catch (UnsupportedEncodingException ex) {
                Logger.getLogger(Util.class.getName()).log(Level.SEVERE, null, ex);
                return null;
            }
        }
    }

    public static String toUTF8(String oldString) {
        if (Util.isBlank(oldString)) {
            return null;
        } else {
            try {
                return new String(oldString.getBytes(), "UTF-8");
            } catch (UnsupportedEncodingException ex) {
                Logger.getLogger(Util.class.getName()).log(Level.SEVERE, null, ex);
                return null;
            }
        }
    }

    public static PrintWriter getPrintWriter(String filename) {
        return getPrintWriter(filename, true);
    }

    public static PrintWriter getPrintWriter(String filename, boolean append) {
        try {
            FileWriter outFile = new FileWriter(filename, append);
            PrintWriter out = new PrintWriter(outFile);
            return out;
        } catch (Exception e) {
            return null;
        }
    }

    public static void generateBuildXML(String dist) {
        File f = new File(dist);

        if (f.isDirectory()) {
            String[] files = f.list();
            for (int i = 0; i < files.length; i++) {
                String s = "<zipfileset src=\"dist\\lib\\" + files[i] + "\"/>";
                Util.println(s);
            }
        } else {
            Util.println("error !");
        }
    }

    public static String getChecksum(File datafile) {
        FileInputStream fis = null;
        try {
            MessageDigest md = MessageDigest.getInstance("SHA1");
            fis = new FileInputStream(datafile);
            byte[] dataBytes = new byte[READ_WRITE_BUF];
            int nread = 0;
            while ((nread = fis.read(dataBytes)) != -1) {
                md.update(dataBytes, 0, nread);
            }
            byte[] mdbytes = md.digest();
            StringBuffer sb = new StringBuffer("");
            for (int i = 0; i < mdbytes.length; i++) {
                sb.append(Integer.toString((mdbytes[i] & 0xff) + 0x100, 16).substring(1));
            }
            return sb.toString();
        } catch (IOException ex) {
            Logger.getLogger(Util.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        } catch (NoSuchAlgorithmException ex) {
            Logger.getLogger(Util.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
    }

    public static String getChecksum(String datafile) {
        return getChecksum(new File(datafile));
    }

    public static boolean ValidateIPAddress(String ipAddress) {
        String[] parts = ipAddress.split("\\.");

        if (parts.length != 4) {
            return false;
        }

        for (String s : parts) {
            int i = Integer.parseInt(s);

            if ((i < 0) || (i > 255)) {
                return false;
            }
        }

        return true;
    }

    public static String stack2string(Exception e) {
        try {
            StringWriter sw = new StringWriter();
            PrintWriter pw = new PrintWriter(sw);
            e.printStackTrace(pw);
            return "------\r\n" + sw.toString() + "------\r\n";
        } catch (Exception e2) {
            return "bad stack2string";
        }
    }
}
